﻿using FPSO.Models.Constant;
using FPSO.Models.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FPSO.Services.Impl
{
    public class ImitateDraughtService : IDraughtService
    {
        public ShipDraught CalcDraught(Dictionary<string, double> tankVolumeDic)
        {
            //1.设定空载时，吃水为5米，纵倾和横倾都是0
            //2.设定满载时，吃水为15米，纵倾和横倾都是0
            //3.通过所有舱室的装载量计算船舯吃水
            //4.根据左边舱室 和 右边舱室的 装载量，计算左舷吃水和右舷吃水 以及 横倾
            //5.根据前面舱室 和 后面舱室的 装载量，计算艏吃水 以及 纵倾斜

            //初始化为空载的情况
            ShipDraught shipDraught = new ShipDraught();
			shipDraught.AftPDraft = 5;
			shipDraught.AftSDraft = 5;
			shipDraught.MidPDraft = 5;
			shipDraught.MidSDraft = 5;
			shipDraught.FwdPDraft = 5;
			shipDraught.FwdSDraft = 5;
            shipDraught.Heel = 5;
            shipDraught.Trim = 5;

            //1.计算全船满载时的装载量
            double maxVolume = TankConstant.GetTankTotleVolume();
            
            double coeffNormal = 1d;
            double coeffMin = 0.8d;

            //当前总容量
            double totalVolume = 0d;
            //NO.3 的舱室在中间，忽略
            //船 前部吃水 NO.5 NO.4 的所有舱室，NO.5系数 1, NO.4系数 0.8
            double frontVolume = 0d;
            //船 尾部吃水 NO.1 NO.2 的所有舱室，NO.1系数 1, NO.2系数 0.8
            double backVolume = 0d;

            //船 左边吃水 S 的船， WBT 系数 1， COT 系数 0.8
            double leftVolume = 0d;
            //船 右边吃水 P 的船， WBT 系数 1， COT 系数 0.8
            double rightVolume = 0d;

            //计算 船前部装载量的系数
            Dictionary<string, double> frontCoeffDic = new Dictionary<string, double>();
            //计算 船后部装载量的系数
            Dictionary<string, double> backCoeffDic = new Dictionary<string, double>();
            //计算 船左边装载量的系数
            Dictionary<string, double> leftCoeffDic = new Dictionary<string, double>();
            //计算 船右边装载量的系数
            Dictionary<string, double> rightCoeffDic = new Dictionary<string, double>();

            //初始化船前部的舱室
            frontCoeffDic.Add("FPT", coeffNormal);
            frontCoeffDic.Add("CO1P", coeffNormal);
            frontCoeffDic.Add("NO1_COT_S", coeffNormal);
            frontCoeffDic.Add("NO1_WBT_P", coeffNormal);
            frontCoeffDic.Add("NO1_WBT_S", coeffNormal);
            frontCoeffDic.Add("NO2_COT_P", coeffMin);
            frontCoeffDic.Add("NO2_COT_S", coeffMin);
            frontCoeffDic.Add("NO2_WBT_P", coeffMin);
            frontCoeffDic.Add("NO2_WBT_S", coeffMin);

            //初始化船后部的舱室 2,1 fpt
            backCoeffDic.Add("NO5_COT_P", coeffNormal);
            backCoeffDic.Add("NO5_COT_S", coeffNormal);
            backCoeffDic.Add("NO5_WBT_P", coeffNormal);
            backCoeffDic.Add("NO5_WBT_S", coeffNormal);
            backCoeffDic.Add("NO4_COT_P", coeffMin);
            backCoeffDic.Add("NO4_COT_S", coeffMin);
            backCoeffDic.Add("NO4_WBT_P", coeffMin);
            backCoeffDic.Add("NO4_WBT_S", coeffMin);
            
            //初始化船左边的舱室
            leftCoeffDic.Add("NO1_WBT_P", coeffNormal);
            leftCoeffDic.Add("NO2_WBT_P", coeffNormal);
            leftCoeffDic.Add("NO3_WBT_P", coeffNormal);
            leftCoeffDic.Add("NO4_WBT_P", coeffNormal);
            leftCoeffDic.Add("NO5_WBT_P", coeffNormal);
            leftCoeffDic.Add("CO1P", coeffMin);
            leftCoeffDic.Add("NO2_COT_P", coeffMin);
            leftCoeffDic.Add("NO3_COT_P", coeffMin);
            leftCoeffDic.Add("NO4_COT_P", coeffMin);
            leftCoeffDic.Add("NO5_COT_P", coeffMin);

            //初始化船右边的舱室
            rightCoeffDic.Add("NO1_WBT_S", coeffNormal);
            rightCoeffDic.Add("NO2_WBT_S", coeffNormal);
            rightCoeffDic.Add("NO3_WBT_S", coeffNormal);
            rightCoeffDic.Add("NO4_WBT_S", coeffNormal);
            rightCoeffDic.Add("NO5_WBT_S", coeffNormal);
            rightCoeffDic.Add("NO1_COT_S", coeffMin);
            rightCoeffDic.Add("NO2_COT_S", coeffMin);
            rightCoeffDic.Add("NO3_COT_S", coeffMin);
            rightCoeffDic.Add("NO4_COT_S", coeffMin);
            rightCoeffDic.Add("NO5_COT_S", coeffMin);

            foreach (KeyValuePair<string, double> tankPair in tankVolumeDic)
            {
                totalVolume += tankPair.Value;

                if (frontCoeffDic.ContainsKey(tankPair.Key))
                {
                    frontVolume += tankPair.Value * frontCoeffDic[tankPair.Key];
                }
                if (backCoeffDic.ContainsKey(tankPair.Key))
                {
                    backVolume += tankPair.Value * backCoeffDic[tankPair.Key];
                }
                if (leftCoeffDic.ContainsKey(tankPair.Key))
                {
                    leftVolume += tankPair.Value * leftCoeffDic[tankPair.Key];
                }
                if (rightCoeffDic.ContainsKey(tankPair.Key))
                {
                    rightVolume += tankPair.Value * rightCoeffDic[tankPair.Key];
                }
            }

            //通过 totalVolume 和 maxVolume 计算平均吃水
            //设定：空载时吃水为5米，满载时吃水为15米
            if (totalVolume >= maxVolume)
            {
                shipDraught.MidPDraft = 15;
				shipDraught.MidSDraft = 15;
			}
			else
            {
                shipDraught.MidPDraft = 5 + (totalVolume / maxVolume) * 10;
				shipDraught.MidSDraft = 5 + (totalVolume / maxVolume) * 10;
			}

			//通过前后 部分舱室 以及 左右 部分舱室的装载量来计算 前后吃水和 横倾和纵倾
			//前后 以及 左右 装载量相差 满载时的 1% 时 设定为倾斜 0.1°， 前后吃水相差 0.1米，左右吃水相差0.03米
			if (Math.Abs(frontVolume - backVolume) > maxVolume * 0.01)
            {
                //船头装载多 0度以下，船尾装载多 0度以上
                shipDraught.Trim = (backVolume - frontVolume) / (maxVolume * 0.01);
                //船头装载多，纵倾为负数，船头吃水深
				shipDraught.FwdPDraft = (shipDraught.MidPDraft + shipDraught.MidSDraft) - shipDraught.Trim * 0.1;
				shipDraught.FwdSDraft = (shipDraught.MidPDraft + shipDraught.MidSDraft) - shipDraught.Trim * 0.1;
            }
            else
            {
                //纵倾为0
                shipDraught.Trim = 0d;
				shipDraught.FwdPDraft = shipDraught.MidPDraft;
				shipDraught.FwdSDraft = shipDraught.MidSDraft;
			}

			if (Math.Abs(leftVolume - rightVolume) > maxVolume * 0.01)
            {
                //左边装载多 0度以下，右边装载多 0度以上
                shipDraught.Heel = (rightVolume - leftVolume) / (maxVolume * 0.01);
                //左边装在多 横倾为负数 左边吃水深
                //shipDraught.LeftDraft = shipDraught.MidDraft - shipDraught.Heel * 0.03;
                //shipDraught.RightDraft = shipDraught.MidDraft + shipDraught.Heel * 0.03;
            }
            else
            {
                //横倾为0
                shipDraught.Heel = 0d;
                //shipDraught.LeftDraft = shipDraught.MidDraft;
                //shipDraught.RightDraft = shipDraught.MidDraft;
            }


            return shipDraught;
        }
    }
}
